﻿/******************************************************************************
 * This file is part of libemb.
 *
 * libemb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libemb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libemb.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Project: Embedme
 * Author : FergusZeng
 * Email  : cblock@126.com
 * git	  : https://git.oschina.net/cblock/embedme
 * Copyright 2014~2017 @ ShenZhen ,China
*******************************************************************************/
#ifndef __TIMER_H__
#define __TIMER_H__

#include "RtcFacade.h"
#include "Event.h"
#include "Thread.h"
#include "Mutex.h"
#include <list>

namespace libemb{
typedef enum
{
    TIMER_TYPE_PERIODIC,
    TIMER_TYPE_ONESHOT,
}TIMER_TYPE_E;

typedef enum
{
    TIME_UNIT_MILLISECOND,
    TIME_UNIT_SECOND,
    TIME_UNIT_MINUTE,
    TIME_UNIT_HOUR,
    TIME_UNIT_DAY,
}TIME_UNIT_E;


class TimerManager;

/**
 *  \file   Timer.h   
 *  \class  Timer
 *  \brief  定时器基类(基于事件消息的定时器)
 */
class Timer{
public:
    Timer(RtcTime_S absTime);
    Timer(int interval,int unit);
    static void msDelay(int ms);
    virtual ~Timer();
    int reset();
    virtual void onTimer(EventCenter* eventCenter)=0;
protected:
    void onTick(EventCenter* eventCenter);
protected:
    int m_type;
    int m_event;
private:
    bool m_isAbsTimer;
    RtcTime_S m_absTime;
    int m_timerMS;
    int m_interval;
    int m_unit;
    bool m_isExpired;
friend class TimerManager;
};

/**
 *  \file   Timer.h   
 *  \class  PeriodicTimer
 *  \brief  周期定时器类	
 */
class PeriodicTimer:public Timer{
public:
    PeriodicTimer(RtcTime_S absTime, int event);
    PeriodicTimer(int interval,int unit, int event);
    ~PeriodicTimer();
private:
    void onTimer(EventCenter* eventCenter);
};

/**
 *  \file   Timer.h   
 *  \class  OneShotTimer
 *  \brief  一次性定时器类	
 */
class OneShotTimer:public Timer{
public:
    OneShotTimer(RtcTime_S absTime, int event);
    OneShotTimer(int interval,int unit, int event);
    ~OneShotTimer();
private:
    void onTimer(EventCenter* eventCenter);
};

/**
 *  \file   Timer.h   
 *  \class  TimerManager
 *  \brief  定时器管理类	
 */
class TimerManager:public Runnable,public EventCenter{
public:
    /**
     *  \brief  获取TimerManager单例
     *  \param  void
     *  \return TimerManager* 
     *  \note   none
     */
    static TimerManager* getInstance()
    {
        static TimerManager instance;
        return &instance;
    }
    ~TimerManager();
    int addTimer(Timer* timer);      /* 增加定时器 */
    int removeTimer(Timer* timer);   /* 移除定时器 */
    int restartTimer(Timer* timer);  /* 重新启用定时器 */
private:
    TimerManager();
    void run();
private:
    MutexLock m_listLock;
    Thread m_timerThread;
    std::list<Timer*> m_timerList;
};

/**
 *  \file   Timer.h   
 *  \class  CTimerProtocol
 *  \brief  CTimer定时回调接口	
 */
class CTimerProtocol{
public:
    CTimerProtocol(){};
    virtual ~CTimerProtocol(){};
    virtual void onCTimer(int timerId);
};

typedef void (CTimerProtocol::*SEL_onctimer)(int);
#define ctimer_selector(SELECTOR) (SEL_onctimer)(&SELECTOR)

/**
 *  \file   CTimer.h   
 *  \class  CTimer
 *  \brief  独占定时器类(基于C回调函数的定时器,每个定时器独占一个线程)
 */
class CTimer:public Runnable{
public:
    CTimer(int id,CTimerProtocol*owner);
    ~CTimer();
    int start(int interval,int unit,SEL_onctimer ontime=NULL);
    int stop();
    int getId(){return m_timerId;}
private:
    void run();
private:
    int m_timerId;
    bool m_startFlag;
    int m_timerMS;
    int m_timeLeft;
    Thread m_mainThread;
    CTimerProtocol* m_owner;
    SEL_onctimer m_ontime;
    bool m_mainThreadExit;
};
}
#endif